/*
 * HTAction.java www.bouthier.net The MIT License : ----------------- Copyright
 * (c) 2001 Christophe Bouthier Permission is hereby granted, free of charge, to
 * any person obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the following
 * conditions: The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software. THE SOFTWARE
 * IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package hypertree.model;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

/**
 * The HTAction class manage the action on the hypertree : drag of a node...
 * 
 * @author Christophe Bouthier [bouthier@loria.fr]
 * @version 1.0
 */
public class HTAction extends MouseAdapter implements MouseMotionListener
{

	private HTDraw		model		= null;	// the drawing model

	private HTCoordE	startPoint	= null;	// starting point of dragging
	private HTCoordE	endPoint	= null;	// ending point of dragging
	private HTCoordS	clickPoint	= null;	// clicked point

	private boolean		kleinMode	= false;

	/* --- Constructor --- */

	/**
	 * Constructor.
	 * 
	 * @param model
	 *            the drawing model
	 */
	public HTAction(HTDraw model)
	{
		this.model = model;
		this.startPoint = new HTCoordE();
		this.endPoint = new HTCoordE();
		this.clickPoint = new HTCoordS();
	}

	/* --- MouseAdapter --- */

	/**
	 * Called when a user pressed the mouse button on the hyperbolic tree. Used
	 * to get the starting point of the drag.
	 * 
	 * @param e
	 *            the MouseEvent generated when clicking
	 */
	@Override
	public void mousePressed(MouseEvent e)
	{
		if (e.isShiftDown())
		{
			this.model.fastMode(true);
		}
		if (e.isControlDown())
		{
			this.model.longNameMode(true);
		}
		this.startPoint.projectionStoE(e.getX(), e.getY(), this.model
				.getSOrigin(), this.model.getSMax());
	}

	/**
	 * Called when a user release the mouse button on the hyperbolic tree. Used
	 * to signal the end of the translation.
	 * 
	 * @param e
	 *            not used here
	 */
	@Override
	public void mouseReleased(MouseEvent e)
	{
		this.model.fastMode(false);
		this.model.longNameMode(false);
		this.model.endTranslation();
	}

	/**
	 * Called when a user clicked on the hyperbolic tree. Used to put the
	 * corresponding node (if any) at the center of the hyperbolic tree.
	 * 
	 * @param e
	 *            the MouseEvent generated when clicking
	 */
	@Override
	public void mouseClicked(MouseEvent e)
	{
		if (e.isShiftDown())
		{
			this.model.restore();
		}
		else if (e.isControlDown())
		{
			this.switchKleinMode();
		}
		else
		{
			this.clickPoint.x = e.getX();
			this.clickPoint.y = e.getY();

			HTDrawNode node = this.model.findNode(this.clickPoint);
			if (node != null)
			{
				this.model.translateToOrigin(node);
			}
		}
	}

	private void switchKleinMode()
	{
		if (this.kleinMode)
		{
			this.kleinMode = false;
		}
		else
		{
			this.kleinMode = true;
		}
		this.model.kleinMode(this.kleinMode);
	}

	/* --- MouseMotionListener --- */

	/**
	 * Called when a used drag the mouse on the hyperbolic tree. Used to
	 * translate the hypertree, thus moving the focus.
	 * 
	 * @param e
	 *            the MouseEvent generated when draging
	 */
	@Override
	public void mouseDragged(MouseEvent e)
	{
		if (this.startPoint.isValid())
		{
			this.endPoint.projectionStoE(e.getX(), e.getY(), this.model
					.getSOrigin(), this.model.getSMax());
			if (this.endPoint.isValid())
			{
				this.model.translate(this.startPoint, this.endPoint);
			}
		}
	}

	/**
	 * Called when the mouse mouve into the hyperbolic tree. Not used here.
	 * 
	 * @param e
	 *            the MouseEvent generated when mouving
	 */
	@Override
	public void mouseMoved(MouseEvent e)
	{
	}

}
